package com.xtm.exercise.base.A12JUC;

import org.junit.Test;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/***
 CopyOnWriteArrayList是一个线程安全、并且在读操作时无锁的ArrayList。
 CopyOnWrite容器即写时复制的容器。

 3-1 如何实现线程安全？
    通俗的理解是当我们往一个容器添加元素的时候，不直接往当前容器添加，而是先将当前容器进行Copy，复制出一个新的容器，然后新的容器里添加元素，添加完元素之后，再将原容器的引用指向新的容器。

    这样做的好处是我们可以对CopyOnWrite容器进行并发的读，而不需要加锁，因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想，读和写不同的容器。
 3-2 特征
 CopyOnWriteArrayList（写数组的拷贝）是ArrayList的一个线程安全的变体，CopyOnWriteArrayList和CopyOnWriteSet都是线程安全的集合，其中所有可变操作（add、set等等）都是通过对底层数组进行一次新的复制来实现的。

 它绝对不会抛出ConcurrentModificationException的异常。因为该列表（CopyOnWriteArrayList）在遍历时将不会被做任何的修改。

 CopyOnWriteArrayList适合用在“读多，写少”的并发场景中，比如缓存、白名单、黑名单。它不存在“扩容”的概念，每次写操作（add or remove）都要copy一个副本，在副本的基础上修改后改变array引用，所以称为“CopyOnWrite”，因此在写操作要加锁，并且对整个list的copy操作时相当耗时的，过多的写操作不推荐使用该存储结构。

 读的时候不需要加锁，如果读的时候有多个线程正在向CopyOnWriteArrayList添加数据，读还是会读到旧的数据，因为开始读的那一刻已经确定了读的对象是旧对象。

 3-3 缺点
 在写操作时，因为复制机制，会导致内存占用过大。
 不能保证实时性的数据一致，“脏读”。

 */
public class CopyOnWriteArrayListDemo {

    @Test
    public void test01(){
        // java.util.concurrent包下
        List<String> list = new CopyOnWriteArrayList<String>();

    }
}
